home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagn_r.zip / NETWORK.SWG / 0028_Ipx-spx Communication unit.pas < prev   
Pascal/Delphi Source File  |  1995-03-03  |  28KB  |  765 lines

  1. {
  2. Reply to NEWS  about IPX/SPX UNIT FOR PASCAL. on 10-20-94
  3. ipx - IPX communication protocol primitives.
  4. }
  5.  
  6. unit ipx;
  7.  
  8. interface uses DOS;
  9.  
  10. type
  11.      MessageStr          = String;
  12.      IPX_REGS            = Registers;
  13.      Byte4               = array[0..3] of byte;
  14.      NetworkNumber       = Byte4;
  15.      NetworkNode         = array[0..5] of byte;
  16.  
  17.      ECB                 = record
  18.                             link_address          : Pointer;
  19.                             event_service_routine : Pointer;
  20.                             in_use                : byte;
  21.                             completion_code       : byte;
  22.                             socket_number         : word;
  23.                             ipx_workspace         : Byte4;
  24.                             driver_workspace      : array[0..11] of 
  25. byte;
  26.                             immediate_address     : NetworkNode;
  27.                             fragment_count          : word;
  28.                             fragment                : array [0..1] of 
  29. record
  30.                                                           address : 
  31. pointer;
  32.                                                           length  : 
  33. word;
  34.                                                     end;
  35.                            end;
  36.  
  37.      IPXHEADER           = record
  38.                             checksum              : word;
  39.                             length                : word;
  40.                             transport_control     : byte;
  41.                             packet_type           : byte;
  42.                             dest_network_number   : NetworkNumber;
  43.                             dest_network_node     : NetworkNode;
  44.                             dest_network_socket   : word;
  45.                             source_network_number : NetworkNumber;
  46.                             source_network_node   : NetworkNode;
  47.                             source_network_socket : word;
  48.                            end;
  49.  
  50. { ZeroEcb - store zeros in all ecb fields.
  51.  Pre: e is an ECB.
  52.         Post: e is fully zeroed. }
  53. procedure ZeroEcb( var e : ECB );
  54.  
  55. { ZeroHeader - Store zeros in all header fields.
  56.  Pre: h is an IPXHEADER.
  57.         Post: h is fulled zeroed. }
  58. procedure ZeroHeader( var h : IPXHEADER );
  59.  
  60. { Get1stConnectionNumber - Return first connection number for user name
  61.  Pre: username is valid Novell user name
  62.         Post: Returns first connection number username is logged on or
  63.          0 if not logged on. }
  64. function Get1stConnectionNumber( username : string ) : word;
  65.  
  66. { GetInternetAddress - Get the network:node address for a connection.
  67.  Pre: connection_number is valid for a logged on user.
  68.         Post: network_number is valid number of network.
  69.          physical_node is valid station node.             
  70.  }
  71. function GetInternetAddress(    connection_number : byte;
  72.                             var network_number : NetworkNumber; {hi:lo}
  73.                             var physical_node : NetworkNode ) : integer;
  74.  
  75. { IPXSPXNotLoaded - Executed when ipxspx called but not loaded.
  76.  Pre: IPX not loaded.
  77.         Post: Execution aborted. }
  78. procedure IPXSPXNotLoaded(var NovRegs : Registers);
  79.  
  80. { IPXInstalled - Determine if IPX is installed on workstation.
  81.  Pre: Either IPX is or is not installed.
  82.         Post:   If IPX installed initialize global IPXLocation to IPX 
  83. entry
  84.          point and return TRUE.
  85.                 Otherwise initialize global IPXLocation to 
  86. IPXSPXNotLoaded
  87.                 entry point and return FALSE.  }
  88. function IPXInstalled : Boolean;
  89.  
  90. { IPXSPX - Call ipxspx at address in IPXLocation.
  91.  Pre: IPXInstalled has been called.
  92.          IPX is installed and NovRegs assigned IPX or SPX 
  93. function
  94.          and parameter values. Not checking is done.
  95.         Post:  IPX or SPX function is called.
  96.          NovRegs assigned by call. }
  97.  
  98. procedure IPXSPX(var NovRegs:Registers);
  99. { IPXRelinquishControl - Give ipx momentary control of CPU.
  100.  Pre: IPX loaded.
  101.         Post: IPX execution done. }
  102.  
  103. procedure IPXRelinquishControl;
  104.  
  105. { IPXCancelEvent - Cancels pending event associated with ECB.
  106.             Pre:  e is valid ECB.
  107.                    Post: 00 - Success.
  108.                      F9 - ECB cannot be canceled.
  109.                          FF - ECB not in use. }
  110. function IPXCancelEvent( var e : ECB ) : byte;
  111.  
  112. { IPXDisconnectFromTarget - Notify listening node that communications 
  113. woth
  114.        specified socket are being terminated.
  115.  Pre: number:node:socket are valid.
  116.         Post: Node notified.   }
  117. procedure IPXDisconnectFromTarget( network_number : NetWorkNumber;
  118.                                    network_node   : NetWorkNode;
  119.                                    network_socket : word );
  120.  
  121. { IPXScheduleEvent - Schedule processing of ECB after timer ticks.
  122.  Pre: ticks is number of 18.2 per second ticks.
  123.                 e is a valid ECB at the time processing occurs.
  124.         Post: e is processed after timer ticks. }
  125. procedure IPXScheduleEvent( ticks : word; var e : ECB );
  126.  
  127. { IPXOpenSocket - Open an application socket.
  128.  Pre: socket to use (BBA-7FFF). All assumed short-lived.
  129.         Post: 00 - Success.
  130.          FE - Socket table full.
  131.                 FF - Socket already open.  }
  132. function IPXOpenSocket( socket : word ) : byte;
  133.  
  134. { IPXCloseSocket - Close socket. No harm if already closed.
  135.  Pre: socket to close.
  136.         Post: socket is closed. }
  137. procedure IPXCloseSocket( socket : word );
  138.  
  139. { IPXListenForPacket - Submit an ECB for use when packet received. Must
  140.                        have ECB available when packet received by IPX.
  141.  Pre: e storage is available when ECB processed by IPX.
  142.          e.socket_number opened.
  143.                 e.event_svc-routine valid routine or NULL.
  144.                 e.fragment_count normally 2.
  145.                 e.fragment[0].address to IPX Header buffer.
  146.                 e.fragment[0].length = 30.
  147.                 e.fragment[1].address to data area <=546 bytes long.
  148.                 e.fragment[1].length = length of data area.
  149.         Post: If socket opened, e is added to pool and return TRUE.
  150.          Otherwise return FALSE.    }
  151. function IPXListenForPacket( var e : ECB ) : Boolean;
  152.  
  153. { IPXSendPacket - Send packet using given ECB.
  154.  Pre: e storage is available when ECB processed by IPX.
  155.          e.socket_number opened.
  156.                 e.event_svc-routine valid routine or NULL.
  157.                 e.immediate_address is address of destination 
  158. workstation.
  159.                 e.fragment_count normally 2.
  160.                 e.fragment[0].address to IPX Header buffer.
  161.                 e.fragment[0].length = 30.
  162.                 e.fragment[1].address to data area <=546 bytes long.
  163.                 e.fragment[1].length = length of data area.
  164.         Post: e.completion_code of: 00 - Message sent.
  165.             FC - Event canceled.
  166.                                         FD - Bad packet.   }
  167.  
  168. { IPXGetLocalTarget - Get the bridge address (or node if not bridged) 
  169. for
  170.         network:node address.
  171.   Pre: dest_network - network number of workstation.
  172.          dest_node    - network node of workstation.
  173.                 dest_socket  - network socket of workstation.
  174.         Post: bridge_address is routing information used by 
  175. IPXSendPacket.
  176.          Return 00 - Success.
  177.                        FA - No path to destination. }
  178. function IPXGetLocalTarget( var dest_network   : NetworkNumber;
  179.                             var dest_node      : NetworkNode;
  180.                                 dest_socket    : word;
  181.                             var bridge_address : NetworkNode ) : byte;
  182.  
  183. { IPXGetIntervalMarker - Return time marker measured in 18.2/sec ticks.
  184.  Pre: None.
  185.         Post: Return time marker. }
  186. function IPXGetIntervalMarker : word;
  187.  
  188. { IPXSend -  Send a packet to network:node:socket using send_ecb and
  189.              send_header. send_ecb/send_header should be defined outside 
  190. of
  191.              IPXSend as both may be in use by ipx after IPXSend 
  192. completes,
  193.              releasing any local variables.
  194.     Pre: dest_network - network number of destination.
  195.  
  196.                 dest_node    - network node of destination.
  197.                 dest_socket  - socket of destination.
  198.                 packet_ptr   - pointer to send packet.
  199.   packet_len   - length of send packet
  200.   send_ecb     - ECB to use for sending.
  201.                 send_header  - IPXHEADER to use for sending.
  202.                 send_socket  - socket to use for sending.
  203.         Post:   If destination reachable, packet is sent. }
  204. procedure IPXSend(  var dest_network   : NetworkNumber;
  205.                     var dest_node      : NetworkNode;
  206.                         dest_socket    : word; { hi:lo }
  207.                         packet_ptr     : Pointer;
  208.                         packet_len     : integer;
  209.                     var send_ecb       : ECB;
  210.                     var send_header    : IPXHEADER;
  211.                      send_socket    : word );
  212.  
  213. { IPXReceive - Submit an ECB/header and storage buffer for a received
  214.          message.
  215.     Pre:    receive_ecb    - ECB allocated for recieving.
  216.   receive_header - IPXHEADER allocated for receiving.
  217.                 receive_socket - socket to receive on.
  218.  Post: message        - area allocated for received message
  219.             holds data.
  220.                 message_size   - size of message area in bytes.  
  221.   }
  222. procedure IPXReceive(  var receive_ecb    : ECB;
  223.                        var receive_header : IPXHEADER;
  224.                            receive_socket : word;
  225.                            message        : Pointer;
  226.                            message_size   : word );
  227. { IPXReceivedFrame - Returns TRUE if message frame received in ECB.
  228.     Pre:    receive_ecb    - ECB allocated for recieving.
  229.  Post: Returns TRUE if message frame received in ECB.  
  230. }
  231. function IPXReceivedFrame( receive_ecb : ECB ) : Boolean;
  232.  
  233.    
  234. {_______________________________________________________________________
  235. __}
  236.  
  237. implementation
  238.    type
  239.      REQUESTBUFFER       = record
  240.                             dest_network_number   : NetWorkNumber;
  241.                             dest_network_node     : NetworkNode;
  242.                             dest_network_socket   : word;
  243.                            end;
  244.      REPLYBUFFER         = record
  245.                             node_address          : NetworkNode;
  246.                            end;
  247.    var IPXLocation : Pointer;              { Address of ipx }
  248.  
  249. { abort - Display message and halt.
  250.    Pre:  message is a string. }
  251. procedure abort( message : string );
  252. begin
  253.      writeln( message );
  254.      Halt(1);
  255. end;
  256.  
  257. {$F+}
  258. { Get1stConnectionNumber - Return first connection number for user name
  259.  Pre: username is valid Novell user name
  260.         Post: Returns first connection number username is logged on or
  261.          0 if not logged on. }
  262. function Get1stConnectionNumber( username : string ) : word;
  263. var
  264.   NovRegs          : Registers;
  265.   Request          : record
  266.                        len            : Word;
  267.                        buffer_type    : Byte;
  268.                        object_type    : Word;
  269.                        name           : string[47];
  270.                      end;
  271.   Reply            : record
  272.                        len                : Word;
  273.                        number_connections : byte;
  274.                        connection_num     : array[0..99] of byte;
  275.                      end;
  276. begin
  277.   with Request do begin
  278.     len  := 51;
  279.     buffer_type := $15;
  280.     object_type := $0100;
  281.     name := username;
  282.   end;
  283.  
  284.   Reply.len := 101;     { Maximum number of user connections }
  285.  
  286.   with NovRegs do begin
  287.     AH := $E3;
  288.     DS := Seg(Request);  {DS:SI points to request}
  289.     SI := Ofs(Request);
  290.     ES := Seg(Reply);    {ES:DI points to reply}
  291.     DI := Ofs(Reply);
  292.     MsDos(NovRegs);
  293.  
  294.     if (Al <> 0) or (Reply.number_connections = 0)
  295.        then Get1stConnectionNumber := 0
  296.        else Get1stConnectionNumber := Reply.connection_num[0];
  297.   end;
  298. end;
  299.  
  300. { GetInternetAddress - Get the network:node address for a connection.
  301.  Pre: connection_number is valid for a logged on user.
  302.         Post: network_number is valid number of network.
  303.          physical_node is valid station node.             
  304.  }
  305. function GetInternetAddress(    connection_number : byte;
  306.                             var network_number : NetworkNumber; {hi:lo}
  307.                             var physical_node : NetworkNode ) : integer;
  308. var
  309.   NovRegs          : Registers;
  310.   Request          : record
  311.                        len               : word;
  312.                        buffer_type       : byte;
  313.                        connection_number : byte;
  314.                      end;
  315.   Reply            : record
  316.                        len            : word;
  317.                        network_number : NetworkNumber;
  318.                        physical_node  : NetworkNode;
  319.                        server_socket  : word;
  320.                      end;
  321. begin
  322.   with Request do begin
  323.     len  := 2;
  324.     buffer_type := $13;
  325.   end;
  326.   Request.connection_number := connection_number;
  327.   Reply.len := 12;
  328.   with NovRegs do begin
  329.     AH := $E3;
  330.     DS := Seg(Request);  {DS:SI points to request}
  331.     SI := Ofs(Request);
  332.     ES := Seg(Reply);    {ES:DI points to reply}
  333.     DI := Ofs(Reply);
  334.     MsDos(NovRegs);
  335.     Ah := 0;
  336.     GetInternetAddress := Ax;
  337.   end;
  338.   network_number := Reply.network_number;
  339.   physical_node := Reply.physical_node;
  340. end;
  341.  
  342. { IPXSPXNotLoaded - Executed when ipxspx called but not loaded.
  343.  Pre: IPX not loaded.
  344.         Post: Execution aborted. }
  345. procedure IPXSPXNotLoaded(var NovRegs : Registers);
  346. begin
  347.      abort('IPX not loaded');
  348. end;
  349.  
  350.  { ZeroEcb - store zeros in all ecb fields.
  351.  Pre: e is an ECB.
  352.         Post: e is fully zeroed. }
  353. procedure ZeroEcb( var e : ECB );
  354. var i : byte;
  355. begin
  356.      with e do begin
  357.           link_address := Ptr(0,0);
  358.           event_service_routine := Ptr(0,0);
  359.           in_use := 0;
  360.           completion_code := 0;
  361.           socket_number   := 0;
  362.           for i := 0 to 3 do
  363.               ipx_workspace[i] := 0;
  364.           for i := 0 to 11 do
  365.               driver_workspace[i] := 0;
  366.           for i := 0 to 5 do
  367.               immediate_address[i] := 0;
  368.           fragment_count := 0;
  369.           for i := 0 to 1 do begin
  370.               fragment[i].address := Ptr(0,0);
  371.               fragment[i].length  := 0;
  372.           end;
  373.      end;
  374. end;
  375.  
  376. { ZeroHeader - Store zeros in all header fields.
  377.  Pre: h is an IPXHEADER.
  378.         Post: h is fulled zeroed. }
  379. procedure ZeroHeader( var h : IPXHEADER );
  380. var i : byte;
  381. begin
  382.    with h do begin
  383.      checksum              := 0;
  384.      length                := 0;
  385.      transport_control     := 0;
  386.      packet_type           := 0;
  387.      for i := 0 to 3 do
  388.          dest_network_number[i] := 0;
  389.      for i := 0 to 5 do
  390.          dest_network_node[i] := 0;
  391.      dest_network_socket   := 0;
  392.      for i := 0 to 3 do
  393.          source_network_number[i] := 0;
  394.      for i := 0 to 5 do
  395.          source_network_node[i] := 0;
  396.      source_network_socket := 0;
  397.   end;
  398. end;
  399.  
  400.  { IPXInstalled - Determine if IPX is installed on workstation.
  401.  Pre: Either IPX is or is not installed.
  402.         Post:   If IPX installed initialize global IPXLocation to IPX 
  403. entry
  404.          point and return TRUE.
  405.                 Otherwise initialize global IPXLocation to 
  406. IPXSPXNotLoaded
  407.                 entry point and return FALSE.  }
  408. function IPXInstalled : Boolean;
  409. var NovRegs          : IPX_REGS;
  410. begin
  411.   with NovRegs do begin
  412.     AX := $7A00;             {func 7Ah of int 2Fh is used to detect IPX}
  413.     Intr($2F,NovRegs);
  414.     if AL = $FF then begin   {if AL is FFh then IPX is loaded and 
  415. available}
  416.       IPXInstalled := TRUE;
  417.       IPXLocation := Ptr(ES,DI); {pointer to IPX entry point in ES:DI}
  418.     end
  419.     else begin
  420.       IPXInstalled := FALSE; {no IPX installed}
  421.       IPXLocation := @IPXSPXNotLoaded;
  422.     end;
  423.   end;
  424. end;
  425.  
  426. { IPXSPX - Call ipxspx at address in IPXLocation.
  427.  Pre: IPXInstalled has been called.
  428.          IPX is installed and NovRegs assigned IPX or SPX 
  429. function
  430.          and parameter values. Not checking is done.
  431.         Post:  IPX or SPX function is called.
  432.          NovRegs assigned by call. }
  433. procedure IPXSPX(var NovRegs:Registers);
  434. var   Ax_, Bx_, Dx_, Di_, Si_, Es_ : word;
  435. begin
  436.      with NovRegs do begin  { Assign simple variables record field 
  437. values }
  438.           Ax_ := Ax;
  439.           Bx_ := Bx;
  440.           Dx_ := Dx;
  441.           Di_ := Di;
  442.           Si_ := Si;
  443.           Es_ := Es;
  444.      end;
  445.  
  446.      asm                            { Assembler instructions. }
  447.         mov   Ax, Ax_               { Initialize CPU registers.}
  448.         mov   Bx, Bx_
  449.         mov   Dx, Dx_
  450.         mov   Di, Di_
  451.         mov   Si, Si_
  452.         mov   Es, Es_
  453.  
  454.         push  Bp
  455.         call  dword ptr IPXLocation { Call IPX via address at 
  456. IPXLocation. }
  457.         pop   Bp
  458.         mov   Ax_, Ax
  459.         mov   Dx_, Dx
  460.      end;
  461.  
  462.      NovRegs.Ax := Ax_;             { Return register values to caller }
  463.      NovRegs.Dx := Dx_;
  464. end;
  465.  
  466. { IPXRelinquishControl - Give ipx momentary control of CPU.
  467.  Pre: IPX loaded.
  468.         Post: IPX execution done. }
  469. procedure IPXRelinquishControl;
  470. var NovRegs : IPX_REGS;
  471. begin
  472.      with NovRegs do begin
  473.           Bx := $0a;
  474.           IPXSPX(NovRegs);
  475.      end
  476. end;
  477.  
  478. { IPXCancelEvent - Cancels pending event associated with ECB.
  479.             Pre:  e is valid ECB.
  480.                    Post: 00 - Success.
  481.                      F9 - ECB cannot be canceled.
  482.                          FF - ECB not in use. }
  483. function IPXCancelEvent( var e : ECB ) : byte;
  484. var NovRegs : IPX_REGS;
  485. begin
  486.      with NovRegs do begin
  487.           Bx := $06;
  488.           ES := Seg(e);    {ES:SI points to ecb}
  489.           SI := Ofs(e);
  490.           IPXSPX(NovRegs);
  491.           IPXCancelEvent := AL;
  492.      end
  493. end;
  494.  
  495. { IPXDisconnectFromTarget - Notify listening node that communications 
  496. woth
  497.        specified socket are being terminated.
  498.  Pre: number:node:socket are valid.
  499.         Post: Node notified.   }
  500. procedure IPXDisconnectFromTarget( network_number : NetWorkNumber;
  501.                                    network_node   : NetWorkNode;
  502.                                    network_socket : word );
  503. var NovRegs : IPX_REGS;
  504.     request_buffer : REQUESTBUFFER;
  505. begin
  506.      with request_buffer do begin
  507.           dest_network_number := network_number;
  508.           dest_network_node   := network_node;
  509.    dest_network_socket := network_socket;
  510.      end;
  511.  
  512.      with NovRegs do begin
  513.           Bx := $0B;
  514.           ES := Seg(request_buffer);    {ES:SI points to ecb}
  515.           SI := Ofs(request_buffer);
  516.           IPXSPX(NovRegs);
  517.      end
  518. end;
  519.  
  520. { IPXScheduleEvent - Schedule processing of ECB after timer ticks.
  521.  Pre: ticks is number of 18.2 per second ticks.
  522.                 e is a valid ECB at the time processing occurs.
  523.         Post: e is processed after timer ticks. }
  524. procedure IPXScheduleEvent( ticks : word; var e : ECB );
  525. var NovRegs : IPX_REGS;
  526. begin
  527.      with NovRegs do begin
  528.           Bx := $05;
  529.           Ax := ticks;
  530.           ES := Seg(e);
  531.           SI := Ofs(e);
  532.           IPXSPX(NovRegs);
  533.      end;
  534. end;
  535.  
  536. { IPXOpenSocket - Open an application socket.
  537.  Pre: socket to use (BBA-7FFF). All assumed short-lived.
  538.         Post: 00 - Success.
  539.          FE - Socket table full.
  540.                 FF - Socket already open.  }
  541. function IPXOpenSocket( socket : word ) : byte;
  542. var NovRegs : IPX_REGS;
  543. begin
  544.      with NovRegs do begin
  545.           Dx := socket;
  546.           Bx := 0;
  547.           Al := 0;
  548.           IPXSPX(NovRegs);
  549.           Ah := 0;
  550.           IPXOpenSocket := Ax;
  551.      end
  552. end;
  553.  
  554. { IPXCloseSocket - Close socket. No harm if already closed.
  555.  Pre: socket to close.
  556.         Post: socket is closed. }
  557. procedure IPXCloseSocket( socket : word );
  558. var NovRegs : IPX_REGS;
  559. begin
  560.      with NovRegs do begin
  561.           Dx := socket;
  562.           Bx := $0001;
  563.           IPXSPX(NovRegs);
  564.      end
  565. end;
  566.  
  567.  { IPXListenForPacket - Submit an ECB for use when packet received. Must
  568.                        have ECB available when packet received by IPX.
  569.  Pre: e storage is available when ECB processed by IPX.
  570.          e.socket_number opened.
  571.                 e.event_svc-routine valid routine or NULL.
  572.                 e.fragment_count normally 2.
  573.                 e.fragment[0].address to IPX Header buffer.
  574.                 e.fragment[0].length = 30.
  575.                 e.fragment[1].address to data area <=546 bytes long.
  576.                 e.fragment[1].length = length of data area.
  577.         Post: If socket opened, e is added to pool and return TRUE.
  578.          Otherwise return FALSE.    }
  579. function IPXListenForPacket( var e : ECB ) : Boolean;
  580. var NovRegs : IPX_REGS;
  581. begin
  582.      with NovRegs do begin
  583.           BX := $0004;
  584.           ES := Seg(e);    {ES:SI points to ecb}
  585.           SI := Ofs(e);
  586.           IPXSPX(NovRegs);
  587.           IPXListenForPacket := Al = 00;
  588.      end
  589. end;
  590.  
  591. { IPXSendPacket - Send packet using given ECB.
  592.  Pre: e storage is available when ECB processed by IPX.
  593.          e.socket_number opened.
  594.                 e.event_svc-routine valid routine or NULL.
  595.                 e.immediate_address is address of destination 
  596. workstation.
  597.                 e.fragment_count normally 2.
  598.                 e.fragment[0].address to IPX Header buffer.
  599.                 e.fragment[0].length = 30.
  600.                 e.fragment[1].address to data area <=546 bytes long.
  601.                 e.fragment[1].length = length of data area.
  602.         Post: e.completion_code of: 00 - Message sent.
  603.             FC - Event canceled.
  604.                                         FD - Bad packet.   }
  605. procedure IPXSendPacket( var e: ECB );
  606. var NovRegs : IPX_REGS;
  607. begin
  608.      with NovRegs do begin
  609.           ES := Seg(e);    {ES:SI points to ecb}
  610.           SI := Ofs(e);
  611.           BX := $0003;
  612.           IPXSPX(NovRegs);
  613.      end
  614. end;
  615.  
  616.  { IPXGetLocalTarget - Get the bridge address (or node if not bridged) 
  617. for
  618.         network:node address.
  619.   Pre: dest_network - network number of workstation.
  620.          dest_node    - network node of workstation.
  621.                 dest_socket  - network socket of workstation.
  622.         Post: bridge_address is routing information used by 
  623. IPXSendPacket.
  624.          Return 00 - Success.
  625.                        FA - No path to destination. }
  626. function IPXGetLocalTarget( var dest_network   : NetworkNumber;
  627.                             var dest_node      : NetworkNode;
  628.                                 dest_socket    : word;
  629.                             var bridge_address : NetworkNode ) : byte;
  630. var
  631.   NovRegs          : Registers;
  632.   Request          : record
  633.                        network_number    : NetworkNumber;
  634.                        physical_node     : NetworkNode;
  635.                        socket            : word;
  636.                      end;
  637.   Reply            : record
  638.                        local_target      : NetworkNode;
  639.                      end;
  640. begin
  641.      with Request do begin
  642.           network_number := dest_network;
  643.           physical_node := dest_node;
  644.           socket := dest_socket;
  645.      end;
  646.      with NovRegs do begin
  647.           Es := Seg(Request);
  648.           Si := Ofs(Request);
  649.           Di := Ofs(Reply);
  650.           Bx := $0002;
  651.           IPXSPX(NovRegs);
  652.           Ah := 0;
  653.           IPXGetLocalTarget := Ax;
  654.           bridge_address := Reply.local_target;
  655.      end
  656. end;
  657.  
  658. { IPXGetIntervalMarker - Return time marker measured in 18.2/sec ticks.
  659.  Pre: None.
  660.         Post: Return time marker. }
  661. function IPXGetIntervalMarker : word;
  662. var
  663.   NovRegs          : Registers;
  664. begin
  665.      with NovRegs do begin
  666.           Bx := $0008;
  667.           IPXSPX(NovRegs);
  668.           IPXGetIntervalMarker := Ax;
  669.      end
  670. end;
  671.  
  672.  { IPXSend - Send a packet to network:node:socket using send_ecb and
  673.              send_header. send_ecb/send_header should be defined outside 
  674. of
  675.              IPXSend as both may be in use by ipx after IPXSend 
  676. completes,
  677.              releasing any local variables.
  678.     Pre: dest_network - network number of destination.
  679.                 dest_node    - network node of destination.
  680.                 dest_socket  - socket of destination.
  681.                 packet_ptr   - pointer to send packet.
  682.   packet_len   - length of send packet
  683.   send_ecb     - ECB to use for sending.
  684.                 send_header  - IPXHEADER to use for sending.
  685.                 send_socket  - socket to use for sending.
  686.         Post:   If destination reachable, packet is sent. }
  687. procedure IPXSend(  var dest_network   : NetworkNumber;
  688.                     var dest_node      : NetworkNode;
  689.                         dest_socket    : word; { hi:lo }
  690.                         packet_ptr     : Pointer;
  691.                         packet_len     : integer;
  692.                     var send_ecb       : ECB;
  693.                     var send_header    : IPXHEADER;
  694.                      send_socket    : word );
  695. begin
  696.      ZeroEcb(send_ecb);
  697.      ZeroHeader(send_header);
  698.      send_ecb.socket_number := send_socket;  { Socket used for sending }
  699.      if IPXGetLocalTarget( dest_network,
  700.            dest_node,
  701.                            dest_socket,
  702.                            send_ecb.immediate_address ) = 0
  703.         then begin
  704.              with send_ecb do begin
  705.                   fragment_count := 2;
  706.                   fragment[0].address := @send_header;
  707.                   fragment[0].length  := sizeof(IPXHEADER);
  708.                   fragment[1].address := packet_ptr;
  709.                   fragment[1].length  := packet_len;
  710.              end;
  711.              with send_header do begin
  712.                   packet_type         := 4;
  713.                   dest_network_number := dest_network;
  714.                   dest_network_node   := dest_node;
  715.                   dest_network_socket := dest_socket;
  716.              end;
  717.              IPXSendPacket( send_ecb );
  718.         end;
  719. end;
  720.  
  721.  { IPXReceive - Submit an ECB/header and storage buffer for a received
  722.          message.
  723.     Pre:    receive_ecb    - ECB allocated for recieving.
  724.   receive_header - IPXHEADER allocated for receiving.
  725.                 receive_socket - socket to receive on.
  726.  Post: message        - area allocated for received message
  727.             holds data.
  728.                 message_size   - size of message area in bytes.  
  729.   }
  730. procedure IPXReceive(  var receive_ecb    : ECB;
  731.                        var receive_header : IPXHEADER;
  732.                            receive_socket : word;
  733.                            message        : Pointer;
  734.                            message_size   : word );
  735. begin
  736.    ZeroEcb(receive_ecb);
  737.    ZeroHeader(receive_header);
  738.    with receive_ecb do begin
  739.         socket_number := receive_socket; { Socket used for receiving }
  740.         fragment_count := 2;
  741.         fragment[0].address := @receive_header;
  742.         fragment[0].length  := sizeof(IPXHEADER);
  743.         fragment[1].address := message;
  744.         fragment[1].length  := message_size;
  745.    end;
  746.     if not IPXListenForPacket( receive_ecb ) then
  747.      abort('IPX Error - Failure initializing.');
  748.    IPXRelinquishControl;              { Give ipx opportunity to process 
  749. }
  750. end;
  751.  
  752. { IPXReceivedFrame - Returns TRUE if message frame received in ECB.
  753.     Pre:    receive_ecb    - ECB allocated for recieving.
  754.  Post: Returns TRUE if message frame received in ECB.  
  755. }
  756. function IPXReceivedFrame( receive_ecb : ECB ) : Boolean;
  757. begin
  758.  IPXReceivedFrame := (receive_ecb.completion_code = 0) and
  759.                             (receive_ecb.in_use = 0);
  760. end;
  761.  
  762. begin
  763. end.
  764.  
  765.